package common

import (
	"encoding/json"
	"fmt"
	"git.mycaigou.com/gfyx/common/authorize"
	"git.mycaigou.com/gfyx/micro-gfyx-api/http_server/controller"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/common/errcode"
	common3 "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/common"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/utils/ossfile"
	"git.mycaigou.com/gfyx/micro-gfyx-api/service/common"
	"git.myscrm.cn/golang/common/ykerrcode"
	"git.myscrm.cn/golang/stark/v4"
	"github.com/gin-gonic/gin"
	"mime"
	"path/filepath"
	"strconv"
)

type FileController struct {
	controller.BaseController
	FileService common.FileSerivceIface
}

// NewFileController
// 构造函数
func NewFileController(fileService common.FileSerivceIface) *FileController {
	return &FileController{FileService: fileService}
}

// 注册路由
func (o *FileController) RegisterRouter(g *gin.RouterGroup) {
	// 简单上传
	g.POST("/file-single-put", o.SinglePut)
	// 获取oss签名
	g.POST("/get-oss-signature", o.GetOssSignature)
	// 保存图片/文件信息
	g.POST("/save-file-info", o.SaveFileInfo)
}

func (o *FileController) SaveFileInfo(ctx *gin.Context) {
	tenantCode := authorize.GetTenantCode(ctx)
	req := common3.SaveFileInfoRequest{}
	if err := ctx.ShouldBind(&req); err != nil {
		stark.Logger.Errorf(ctx.Request.Context(), "SaveFileInfo 参数错误:%s", err.Error())
		o.Fail(ctx, errcode.COMMON_ERROR, "参数不合法 "+err.Error())
		return
	}
	isPrivate := int64(1)
	fileUid, err := o.FileService.SaveToFile(ctx, req.FilePath, req.FileType, req.FileName, req.Business, req.FileSize, isPrivate, tenantCode)
	if err != nil {
		o.Fail(ctx, ykerrcode.FAIL, err.Error())
		return
	}
	if fileUid == "" {
		o.Fail(ctx, ykerrcode.FAIL, "文件id获取不到")
		return
	}
	saveFileInfoResponse := &common3.SaveFileInfoResponse{
		Uid: fileUid,
	}
	o.Success(ctx, saveFileInfoResponse)
}

func (o *FileController) GetOssSignature(ctx *gin.Context) {
	tenantCode := authorize.GetTenantCode(ctx)
	var params = make(map[string]interface{})
	err := json.NewDecoder(ctx.Request.Body).Decode(&params)
	if err != nil {
		o.Fail(ctx, errcode.COMMON_ERROR, "参数有误"+err.Error())
		return
	}
	business, _ := params["business"].(string)
	if business == "" {
		o.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "business 不能为空")
		return
	}

	// 存储到文件表
	policyToken, err := o.FileService.GetPolicyToken(ctx, business, tenantCode)
	if err != nil {
		o.Fail(ctx, ykerrcode.FAIL, err.Error())
		return
	}
	o.Success(ctx, policyToken)
}

func (o *FileController) SinglePut(ctx *gin.Context) {
	tenantCode := authorize.GetTenantCode(ctx)
	// 对form表单传过来的文件进行读取
	file, err := ctx.FormFile("sfile")
	if err != nil {
		o.Fail(ctx, errcode.COMMON_PARAMS_ERROR, err.Error())
		return
	}
	if file == nil {
		o.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "文件不能为空")
		return
	}
	if file.Size > ossfile.PUT_FILE_MAX_BYTES {
		o.Fail(ctx, errcode.COMMON_PARAMS_ERROR, fmt.Sprintf("文件大小超过%sM", strconv.Itoa(ossfile.PUT_FILE_MAX_BYTES/1024/1024)))
		return
	}
	// 业务模块，映射到桶下面的文件夹
	business := ctx.PostForm("business")
	if business == "" {
		o.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "business不能为空")
		return
	}
	if len(business) > 40 {
		o.Fail(ctx, errcode.COMMON_PARAMS_ERROR, "business过长")
		return
	}
	isPrivate := int64(1)
	ossFilePath, signedURL, err := ossfile.PutOss(file, business, 1, tenantCode)
	if err != nil {
		o.Fail(ctx, ykerrcode.FAIL, err.Error())
		return
	}
	//fileExt := path.Ext(file.Filename)
	extension := filepath.Ext(file.Filename)
	contentType := mime.TypeByExtension(extension)
	if contentType == "" {
		contentType = "unknown"
	}
	// 存储到文件表
	fileUid, err := o.FileService.SaveToFile(ctx, ossFilePath, contentType, file.Filename, business, file.Size, isPrivate, tenantCode)
	if err != nil {
		o.Fail(ctx, ykerrcode.FAIL, err.Error())
		return
	}
	if fileUid == "" {
		o.Fail(ctx, ykerrcode.FAIL, "文件id获取不到")
		return
	}
	getFileResponse := &common3.GetFileResponse{
		Url:        signedURL,
		Uid:        fileUid,
		Type:       contentType,
		Name:       file.Filename,
		Path:       ossFilePath,
		Size:       file.Size,
		IsPrivate:  isPrivate,
		TenantCode: tenantCode,
	}
	//fileRes := fmt.Sprintf("https://%s.%s/%s", bucketName, endpoint, ossFilePath)
	file = nil
	o.Success(ctx, getFileResponse)
}
